package com.gexada.solr.dataimport;

import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.params.MapSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.core.SolrCore;
import org.apache.solr.handler.dataimport.Context;
import org.apache.solr.handler.dataimport.EventListener;
import org.apache.solr.handler.dataimport.RecordableDocBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gexada.solr.dataimport.http.HttpClientHelper;

public class AfterImportLitener implements EventListener {

	private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

	private static final String DEST = "http://localhost:3000";

	@SuppressWarnings("unchecked")
	@Override
	public void onEvent(Context ctx) {

		Set<Map<String, Object>> deltas = (Set<Map<String, Object>>) ctx
				.getSessionAttribute(RecordableDocBuilder.COLLECT_DELTA, Context.SCOPE_GLOBAL);
		if (deltas == null) {
			return;
		}
		try {
			String body = buildJson(doQuery(buildSolrParams(deltas), ctx.getSolrCore()));
			send(DEST, body);
		} catch (Exception e) {
			log.warn("Can not send to " + DEST, e);
		}
	}

	private SolrParams buildSolrParams(Set<Map<String, Object>> deltas) {
		StringBuilder sb = new StringBuilder();
		for (Map<String, Object> delta : deltas) {
			for (Map.Entry<String, Object> s : delta.entrySet()) {
				sb.append(s.getKey()).append(":").append(s.getValue()).append(" OR ");
			}
		}
		String qStr = sb.toString();
		if (sb.length() > 0) {
			qStr = sb.substring(0, sb.length() - " OR ".length());
		}
		Map<String, String> pmap = new HashMap<>();
		pmap.put("q", qStr);
		return new MapSolrParams(pmap);
	}

	private String buildJson(QueryResponse resp) throws JsonProcessingException {
		SolrDocumentList list = resp.getResults();
		List<Map<String, String>> jsonO = new ArrayList<>();
		for (SolrDocument doc : list) {
			Map<String, Object> fieldMap = doc.getFieldValueMap();
			Map<String, String> sMap = new HashMap<>();
			for (String field : fieldMap.keySet()) {

				sMap.put(field, fieldMap.get(field).toString());

			}
			jsonO.add(sMap);
		}
		ObjectMapper om = new ObjectMapper();
		return om.writeValueAsString(jsonO);
	}

	private QueryResponse doQuery(SolrParams params, SolrCore core) throws SolrServerException, IOException {
		// 不要关闭，这里的SolrCore是整个服务器使用的，不需要单独关闭
		@SuppressWarnings("resource")
		EmbeddedSolrServer solrServer = new EmbeddedSolrServer(core);
		return solrServer.query(params);
	}

	private void send(String url, String entity) throws URISyntaxException, ClientProtocolException, IOException {
		HttpPost post = new HttpPost(new URL(url).toURI());
		StringEntity body = new StringEntity(entity, "utf-8");
		// entity.setContentEncoding("UTF-8");
		body.setContentType("application/json");
		post.setEntity(body);
		HttpClientHelper.execute(post);
	}

}
